
#include <iostream>
#include "mvPubApi.h"

#include <time.h>
#include <sys/time.h>

//ip mac
#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fstream>
#include <string>
#include <cstdio>

std::vector<std::string> SplitString(const std::string& str, const std::string& delimiter, const bool trim_empty) {
    size_t position, last_position = 0, length;
    std::vector<std::string> tokens;
    while (true) {
        position = str.find(delimiter, last_position);
        if (position == std::string::npos) {
            position = str.size();
        }
        length = position - last_position;
        tokens.push_back(str.substr(last_position, length));
        if (position == str.size()) {
            break;
        } else {
            last_position = position + delimiter.size();
        }
    }
    return tokens;

}

std::string TrimString(const std::string& str) {
    std::string blank = "\r\n\t ";
    size_t begin = str.size(), end = 0;
    for (size_t i = 0; i < str.size(); ++i) {
        if (blank.find(str[i]) == std::string::npos) {
            begin = i;
            break;
        }
    }
    for (size_t i = str.size(); i > 0; --i) {
        if (blank.find(str[i - 1]) == std::string::npos) {
            end = i - 1;
            break;
        }
    }
    if (begin >= end) { return ""; }
    else { return str.substr(begin, end - begin + 1); }
}

//-------------------------------------------------------------------------
//获取当前设备IP
std::string getLocalIP() {
    struct ifaddrs *ifaddr, *ifa;
    int family, s;
    char host[NI_MAXHOST];

    // 获取所有网络接口的信息
    if (getifaddrs(&ifaddr) == -1) {
        perror("getifaddrs");
        exit(EXIT_FAILURE);
        return "";
    }

    // 遍历所有网络接口，找到eth0
    for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
        if (ifa->ifa_addr == NULL)
            continue;

        family = ifa->ifa_addr->sa_family;

        if (strcmp(ifa->ifa_name, "eth0") == 0 && family == AF_INET) {
            s = getnameinfo(ifa->ifa_addr,
                            sizeof(struct sockaddr_in),
                            host, NI_MAXHOST,
                            NULL, 0, NI_NUMERICHOST);

            if (s != 0) {
                printf("getnameinfo() failed: %s\n", gai_strerror(s));
                exit(EXIT_FAILURE);
            }

            printf("eth0 IP address: %s\n", host);
            break;
        }
    }

    freeifaddrs(ifaddr);
    std::string strIP = "";
    strIP.assign(host);
    return strIP;
}

//获取当前udppush client id
char * getLocalClientID() {
    return m_localClientID;
}

//设置udppush client id
void setLocalClientID(std::string sClientIP) {
    m_localClientID = new char[sClientIP.length() + 1];
    strcpy(m_localClientID, sClientIP.c_str());
    //m_localClientID = clientID;
}

//-------------------------------------------------------------------------
//获取当前设备MAC地址
std::string getLocalMacAddress() {
    std::ifstream file("/sys/class/net/eth0/address");
    std::string macAddress;

    if (file.is_open()) {
        std::getline(file, macAddress);
        file.close();
    }
    std::cout << "MAC: " << macAddress << std::endl;
    return macAddress;
}


//-------------------------------------------------------------------------
//获取当前时间戳
std::string getCurrentTimestamp() {
    // 获取当前时间戳
    auto now = std::chrono::system_clock::now();

    // 将时间戳转换为时间点类型
    std::chrono::time_point<std::chrono::system_clock> timePoint(now);

    // 将时间点转换为时间戳（秒级）
    std::time_t timeStamp = std::chrono::system_clock::to_time_t(timePoint);

    // 打印时间戳
    std::cout << "Timestamp: " << timeStamp << std::endl;

    std::stringstream ss;

    ss << timeStamp;

    return ss.str();
}

//获取到通道号
std::string getChannelID() {
    return m_sChannelID;
}

//获取到会话ID
std::string getSessionID() {
    return m_sID;
}

//读取json配置
std::string readJsonConfig(const char* file_name) {
    if(strcmp(file_name, "") == 0) return "";
    Json::Reader reader;
    Json::Value json_root;

    std::ifstream in;

    bool open_status = open_config_file(reader, json_root, in, file_name);
    if(!open_status) return "";
    if (json_root.isMember("Info")) {
        m_iDevDirect = json_root["Info"]["DevDirect"].asInt();
        m_iSwipeCardTimeOut = json_root["Info"]["SwipeCardTimeOut"].asInt();
        m_sChannelID = json_root["Info"]["ChannelNo"].asString();
        m_sUnitId = json_root["Info"]["UnitId"].asString();
        m_iCarWindowDetect = json_root["Info"]["CarWindowDetect"].asInt();
        m_iTakeAwayCardTimeOut = json_root["Info"]["TakeAwayCardTimeOut"].asInt();
    }

    if (json_root.isMember("Push")) {
        m_sPushIP = json_root["Push"]["IP"].asString();
        m_iPushPort = json_root["Push"]["Port"].asInt();
    }

    if (json_root.isMember("Platform")) {
        m_iPlatformPort = json_root["Platform"]["Port"].asInt();
        m_sPlatformIP = json_root["Platform"]["IP"].asString();
        m_sPlatformInterface = json_root["Platform"]["Interface"].asString();
    }

    in.close();

    InfoL << m_sChannelID << m_sPlatformIP << m_sPushIP;

    std::string sJson = std::to_string(m_iSwipeCardTimeOut) + "," + std::to_string(m_iCarWindowDetect) + "," + m_sPushIP
    + "," + std::to_string(m_iPushPort) + "," + m_sPlatformIP + "," + std::to_string(m_iPlatformPort) + "," + m_sPlatformInterface + "," + std::to_string(m_iDevDirect)
    + "," + std::to_string(m_iTakeAwayCardTimeOut);
    return sJson;
}

/**
* @brief open config file
*
* @author zzk
* @date 2022-06-22 15:24:53
* @version
* @param reader Json Reader Object
* @param root   Json Value Object
* @param in
* @param file_name json file name
*
* @return is file open and parse correctly
*/
bool open_config_file(Json::Reader &reader, Json::Value& root, std::ifstream& in, const char* file_name) {
    bool file_status = false; // If file is exist and json content is normal, set true value.
    in.open(file_name, std::ios::binary);

    if(!in.is_open()) {
        auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
        fprintf(stderr, "----------------------------current timestamp :%lld------Error Opening json file:%s\n", ms.count(), file_name);
        return file_status;
    }

    file_status = reader.parse(in, root);
    if(!file_status) {
        in.close();
        in.clear();

        auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
        fprintf(stderr, "----------------------------current timestamp :%lld------bk file is broken too.\n", ms.count());
    }

    return file_status;
}

//获取文件数据
std::string getFileData(const std::string filePath) {
    std::string strFile;
	std::ifstream is;   //输入流
	is.open(filePath, std::ifstream::in | std::ios::binary);
	if(!is.is_open())
	{
		return "";
	}
	is.seekg(0, is.end);
	int length = is.tellg();
	is.seekg(0, is.beg);
	// 3. 创建内存缓存区
	char buffer[length]={0};
	// 4. 读取图片
	is.read(buffer, length);
	for (size_t i = 0; i < length; i++)
	{
		strFile += buffer[i];
	}
	InfoL << "size: " << ("=================strFile.size()=%d",strFile.size());
	is.close();
    return strFile;
}

//判断文件是否存在
bool fileExists(const std::string filePath) {
    std::ifstream file(filePath);
    return file.good();
}

//删除文件
bool fileDelete(const std::string filePath) {
    if (fileExists(filePath)) {
        if (std::remove(filePath.c_str()) != 0) {
            return false;
        }
        return true;
    } else {
        return false;
    }
}
